#!usr/bin/env python
# -*- coding: iso-8859-15 -*-

import urllib
import re

## TODO: --> Search cities with only one word (for example, "Viana" should find
##       "Viana do Castelo")
##       --> Create an update_cache method (maybe call it once every hour and
##       then delete the file when with the __del__ method?)
##       --> Check the diferences between the get_information and the
##       search_city


class Client:
    """Connects to the Portuguese weather institute to see the weather
    conditions and the temperature of several Portuguese cities.


    Check what cities you can search in the following web page:
        http://www.meteo.pt/pt/html.jsp
    """

    def __init__(self):
        ## TODO: Make a better check to see if the computer is connected to
        ##       the Internet.
        try:
            self.page = urllib.urlopen("http://www.meteo.pt/pt/html.jsp")
        except IOError:
            # Connection to teh tubes FAIL
            print "There isn't a connection to the Internet"

        # Format the content of the web page
        tmp_content = self.page.readlines()
        self.content = []
        saving = 0 # The page is divided into 2 tables, so we only start
                   # saving things when this reaches 2
        for line in tmp_content:
            line = line.replace("\n", "").replace("\r", "")
            if saving == 2:
                self.content.append(line)
            if "tablelist_wid" in line:
                saving += 1
            else:
                pass

        self.content = "\n".join(self.content)

        # Cities not working: braganca, evora
        # Cities removed from the web page: angra do heroismo, santarem, guarda
        #      braga,
        # New cities: Evora, Flores, Ponta Delgada, Porto Santo,
        #             Viana do Castelo, Vila Real, Viseu
        self.known_cities= (
                "beja", "braganca", "cabo carvoeiro", "castelo branco",
                "coimbra", "evora", "faro", "flores", "funchal", "horta",
                "lisboa", "ponta delgada", "penhas douradas", "portalegre",
                "porto", "porto santo", "sagres", "sines", "viana do castelo",
                "viana castelo", "vila real", "viseu")
                # "bragan?, "?ra")

        # This will be used in the future, ignore it for now (it does nothing)
        #self.city_convertion = {
        #        "braganca": "bragan?,
        #        "evora": "?ra",
        #        ## TODO: Finish this thing
        #        }

        self.pattern = re.compile(r"""
            # The .*? at the end of the lines is so remove the \t
            # characters that appear in the page source

            <tr\ class="tablelist_bg[01]">.*?   # Start of a city's information
            <td> (.*?) </td>.*?                 # Name of the city
            <td\ align="center"> (.*?) </td>.*? # Weather Status
            <td\ align="center"> (.*?) </td>.*? # Temperature
            <td\ align="center"> (.*?) </td>.*? # Velocity of the wind
            <td\ align="center"> (.*?) </td>.*? # Direction of the wind
            <td\ align="center"> (.*?) </td>.*? # Humidity (percentage)
            <td\ align="center"> (.*?) </td>.*? # Precipitation (mm)
            <td\ align="center"> (.*?) </td>.*? # Pressure (hPa)
            <td\ align="center"> (.*?) </td>.*? # Mist (percentage)
            <td\ align="center"> (.*?) </td>    # Snow (cm)
            """, re.DOTALL | re.VERBOSE)

    def search_city(self, city_name):
        """Search the web page source code and retrieve the information that
        exists for the city "city_name"

        Returns a tuple with the information in the following order:
            (
                Name of the city,
                Weather,
                Temperature (ºC),
                Speed of the wind (km/h),
                Direction of the wind (cardinal points),
                Humidity in the air (%),
                Precipitation (mm),
                Pressure (hPa),
                Mist in the air (%),
                Snow on the ground (cm)
            )

        If the web page doesn't have some the information for the city, that
        stat will get the value of "---"

        """
        city_name = city_name.capitalize()

        if city_name == "Viana do castelo": # Workaround (city is called Viana
                                            # Castelo in the web page)
            city_name = "Viana"

        results = re.findall(self.pattern, self.content)

        for line in results:

            line = list(line) # re.findall return a list of tuples, so we
                              # need to convert the tuple to a list so we can
                              # make some changes into it

            # Remove additional stuff from the name
            line[0] = line[0].split("(")[0].strip()
            # So it stays the same as the city_name
            line[0] = line[0].capitalize()

            # These two cities have a similar names, so we need to work around
            # them
            if city_name == "Porto" and city_name == line[0]:
                return line
            elif city_name == "Porto santo" and city_name in line[0]:
                return line

            elif city_name in line[0]:
                return line

    def get_information(self, city):
        """Get information for the city from the web page's source.

        Returns a tuple with the information about the city in the
        following format:
            (
                Name of the city,
                Weather,
                Temperature (ºC),
                Speed of the wind (km/h),
                Direction of the wind (cardinal points),
                Humidity in the air (%),
                Precipitation (mm),
                Pressure (hPa),
                Mist in the air (%),
                Snow on the ground (cm)
            )

        If the web page doesn't have some the information for the city, that
        stat will get the value of "Informacao nao disponivel"

        Returns 1 if the city doesn't exist in the web page.
        """
        if city.lower() not in self.known_cities:
            return 1
        else:
            #pdb.set_trace()
            tmp_result = self.search_city(city)
            result = []
            for info in tmp_result:
                if info == "---":
                    result.append("Informacao nao disponivel")
                else:
                    result.append(info)
            return tuple(result)


if __name__ == "__main__":
    c = Client()
    (place, weather, temp, vel_wind, dir_wind, humidity, rain, pressure,
            mist, snow) = c.get_information("Porto")
    print "Estado do tempo:", weather
    print "Temperatura:", temp
